#define _EKOS_KERNEL_C_

#include <kernel/kernel.h>

void
handle_signal(struct trapframe_t tf)
{
     struct env_t *env = envs + cur_env;
     /* 若干限制条件 */

     /* 不能处在异常态 */
     if (env->xinfo.level != 0) return;
     /* 不能处在内核态 */
     if (tf.cs == GD_KERN_TEXT) return;

     /* 当前存在未被处理的信号 */
     if (env->signal_lock == 0) return;
     
     int signal;
     /* 不在处理中 */
     if ((signal = env->signal) == 0) return;
     env->signal = 0;

#ifdef K_SIGNAL_DEBUG
     kprintf("[handle_signal] recive signal %d, env id %d\n", signal, env->eid);
#endif

     char *old_esp, *esp = (char *)tf.stk.esp;
     old_esp = esp;
     
     esp -= sizeof(struct trapframe_t);
     memmove(esp, &tf, sizeof(struct trapframe_t));
     
     esp -= sizeof(int);
     *(int *)esp = signal;
     
     call_rpc(&env->signal_handler, (GPREG_T)esp, NULL);
     esp = old_esp;

     /* sl_release(&env->signal_lock); */
     /* ??? 要不要在这里解开锁呢 */
}
